function [classifier, min_error, best_labels] = decision_stump(data, weight, label)
% decision_stump 确定最优决策树桩并返回分类函数
% data:num_row*num_col; weights:num_row*1(初始值均为1/num_row); labels:num_row*1(初始值为1或0)
% classifier有dim(哪一维特征识别率最高),thresh_val(阈值何值时候该维征识别率最高),thresh_ineq(是大于阈值识别高还是小于阈值识别高)
num_row = size(data, 1);
num_col = size(data, 2);
% 优化迭代次数
max_iter = 10;
% 初始化相关参数
min_error = Inf;
best_labels = ones(num_row , 1);
classifier.dim = 0;
classifier.thresh_val = 0;
classifier.thresh_ineq = '';
for i = 1:num_col
    cur_thresh_val = min(data(:, i));
    step_size = (max(data(:, i)) - min(data(:, i))) / max_iter;
    for j = 1:max_iter
        for k = ['l', 'g']
            thresh_val = cur_thresh_val + (j - 1) * step_size;
            predi_labels = decision(data, i, thresh_val, k);
            err = sum(weight .* (predi_labels ~= label));
            fprintf("iter %d dim %d, threshVal %.2f, thresh ineqal: %s, the weighted error is %.3f\n", j, i, thresh_val, k, err);
            if err < min_error
                %更新相关参数
                min_error = err;
                best_labels = predi_labels;
                classifier.dim = i;
                classifier.thresh_val = thresh_val;
                classifier.thresh_ineq = k;
            end
        end
    end
end
end

% 根据决策树桩的阈值来分类(1,0)
function predi_labels = decision(data, i_col, thresh_val, thresh_ineq)
% data:num_row*num_col,i_col:表示第i列,thresh_val:表示决策树桩的阈值,thresh_ineq:采用大于或者小于来比较阈值
% predi_labels:根据决策树桩的阈值来获得分类后的labels,num_row*1
num_row = size(data, 1);
% 初始化predi_labels为全1
predi_labels = ones(num_row, 1);
if thresh_ineq == 'l'
    % 如果小于阈值,则判定为0
    predi_labels(data(:, i_col) <= thresh_val) = 0;
elseif thresh_ineq == 'g'
    % 如果大于阈值,则判定为0
    predi_labels(data(:, i_col) > thresh_val) = 0;
end
end